// 06_enums_and_pattern_matching.rs
// Rust 枚举和模式匹配教程

// 1. 定义枚举
#[derive(Debug)]
enum IpAddrKind {
    V4,
    V6,
}

// 2. 将数据直接关联到枚举成员
#[derive(Debug)]
enum IpAddr {
    V4(String),
    V6(String),
}

// 3. 枚举成员可以有不同的数据类型
#[derive(Debug)]
enum IpAddrAdvanced {
    V4(u8, u8, u8, u8),
    V6(String),
}

// 4. 带有关联值的枚举示例
#[derive(Debug)]
enum Message {
    Quit,                           // 没有关联数据
    Move { x: i32, y: i32 },       // 包含匿名结构体
    Write(String),                  // 包含单独的 String
    ChangeColor(i32, i32, i32),    // 包含三个 i32
}

// 5. 为枚举定义方法
impl Message {
    fn call(&self) {
        // 在这里定义方法体
        println!("调用消息: {:?}", self);
    }
}

fn main() {
    // 6. 创建枚举实例
    let four = IpAddrKind::V4;
    let six = IpAddrKind::V6;
    
    // 7. 使用枚举
    route(IpAddrKind::V4);
    route(IpAddrKind::V6);
    
    // 8. 带有关联值的枚举实例
    let home = IpAddr::V4(String::from("127.0.0.1"));
    let loopback = IpAddr::V6(String::from("::1"));
    
    println!("家庭地址: {:?}", home);
    println!("回环地址: {:?}", loopback);
    
    // 9. 高级枚举实例
    let home = IpAddrAdvanced::V4(127, 0, 0, 1);
    let loopback = IpAddrAdvanced::V6(String::from("::1"));
    
    println!("高级家庭地址: {:?}", home);
    println!("高级回环地址: {:?}", loopback);
    
    // 10. 消息枚举实例
    let m = Message::Write(String::from("hello"));
    m.call();
    
    // 11. Option 枚举（标准库中的枚举）
    let some_number = Some(5);
    let some_string = Some("a string");
    let absent_number: Option<i32> = None;
    
    println!("Some 数字: {:?}", some_number);
    println!("Some 字符串: {:?}", some_string);
    println!("None 数字: {:?}", absent_number);
    
    // 12. match 控制流运算符
    let coin = value_in_cents(Coin::Quarter(UsState::Alaska));
    println!("硬币价值: {} 美分", coin);
    
    // 13. 使用 match 处理 Option<T>
    let five = Some(5);
    let six = plus_one(five);
    let none = plus_one(None);
    
    println!("five: {:?}, six: {:?}, none: {:?}", five, six, none);
    
    // 14. 通配符模式
    let some_u8_value = 0u8;
    match some_u8_value {
        1 => println!("one"),
        3 => println!("three"),
        5 => println!("five"),
        7 => println!("seven"),
        _ => println!("其他值"),  // 通配符模式
    }
    
    // 15. if let 简单控制流
    let some_u8_value = Some(0u8);
    match some_u8_value {
        Some(3) => println!("three"),
        _ => println!("其他值"),
    }
    
    // 等价于上面的 match
    if let Some(3) = some_u8_value {
        println!("three");
    } else {
        println!("其他值");
    }
    
    // 16. 使用 if let 处理枚举
    let coin = Coin::Quarter(UsState::Alaska);
    let mut count = 0;
    match coin {
        Coin::Quarter(state) => println!("这是 {:?} 的 25 美分硬币!", state),
        _ => count += 1,
    }
    
    // 使用 if let 简化
    let coin = Coin::Penny;
    if let Coin::Quarter(state) = coin {
        println!("这是 {:?} 的 25 美分硬币!", state);
    } else {
        count += 1;
        println!("计数增加到: {}", count);
    }
}

// 6. 函数参数使用枚举
fn route(ip_kind: IpAddrKind) {
    println!("路由 IP 地址类型: {:?}", ip_kind);
}

// 12. match 示例：美分硬币
#[derive(Debug)]
enum Coin {
    Penny,
    Nickel,
    Dime,
    Quarter(UsState),
}

#[derive(Debug)]
enum UsState {
    Alabama,
    Alaska,
    // ... 其他州
}

fn value_in_cents(coin: Coin) -> u8 {
    match coin {
        Coin::Penny => {
            println!("幸运 penny!");
            1
        },
        Coin::Nickel => 5,
        Coin::Dime => 10,
        Coin::Quarter(state) => {
            println!("这是 {:?} 的硬币", state);
            25
        },
    }
}

// 13. 使用 match 处理 Option<T>
fn plus_one(x: Option<i32>) -> Option<i32> {
    match x {
        None => None,
        Some(i) => Some(i + 1),
    }
}